package com.avl;

import java.util.Map;

public class Node {
    int value;
    Node left;
    Node right;

    public Node(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    /**
     * 添加结点：以递归的形式添加结点，满足二叉排序树的特点
     */
    public void add(Node node){
        if(node == null){
            return;
        }
        if(node.value < this.value){
            if(this.left != null){
                this.left.add(node);
            }else {
                this.left = node;
            }
        }else {
            if(this.right != null){
                this.right.add(node);
            }else {
                this.right = node;
            }
        }
        //当添加结点时，右子树的高度比左子树高度绝对值大于1时，通过左旋转降低右子树的高度
        if(this.rightHeight() - this.leftHeight() > 1){
            //左旋转时，结点右子树的左子树高度大于右子树的右子树的高度，先对结点右子树进行右旋转
            if(this.right.leftHeight() > this.right.rightHeight()){
                this.right.rightHeight();
            }
            leftRotate();
            return;
        }
        if(this.leftHeight() - this.rightHeight() > 1){
            //进行右旋转时，如果该结点的左子树的右子树高度大于该结点左子树的左子树的高度，左旋转后仍为非平衡二叉树
            //需要先对该结点的左子树进行左旋转，再对该结点进行右旋转
            if(this.left.rightHeight() > this.left.leftHeight()){
                this.left.leftRotate();
            }
            rightRotate();
        }
    }
    /**
     * 中序遍历
     */
    public void infixOrder(){
        if(this.left != null){
            this.left.infixOrder();
        }
        System.out.println(this);
        if(this.right != null){
            this.right.infixOrder();
        }
    }
    /**
     * 根据value查找到对应的结点和父结点并保存在map中
     */
    public void search(int value, Map<String,Node> map){
        if(value == this.value){
            map.put("curNode",this);
            return ;
        }else if(value > this.value){
            if(this.right != null){
                map.put("parNode",this);
                this.right.search(value,map);
            }
        }else {
            if(this.left != null){
                map.put("parNode",this);
                this.left.search(value,map);
            }
        }
        //待查找的value不存在
       if(map.get("curNode") == null){
           map.clear();
       }
        return;
    }

    /**
     * 统计树的高度
     * 使用递归统计树的高度，在递归到叶子结点时，叶子结点的左右子树都为null，此时返回0+1.即叶子结点高度为1..回溯的过程依次+1
     */
    public int height(){
        return Math.max(left == null ? 0 : left.height(),right == null ? 0 : right.height())+1;
    }

    /**
     * 返回左子树的高度
     */
    public int leftHeight(){
        if(left == null){
            return 0;
        }else {
            return left.height();
        }
    }

    /**
     * 返回右子树的高度
     */
    public int rightHeight(){
        if(right == null){
            return 0;
        }else {
            return right.height();
        }
    }

    /**
     * 左旋转
     */
    public void leftRotate(){
        //1.创建一个新的节点 newNode，新节点值等于当前根节点的值(从root开始选择
        Node newNode = new Node(this.value);
        //2.新节点的左子树，设置成当前节点的左子树
        newNode.left = this.left;
        //3.新节点的右子树，设置成当前节点的右子树的左子树
        newNode.right = this.right.left;
        //当前节点的值，换为右子节点的值
        this.value = this.right.value;
        //当前节点的右子树，设置成右子树的右子树
        this.right = this.right.right;
        //当前节点的左子树，设置为(指向)新节点
        this.left = newNode;
    }
    /**
     * 右旋转
     */
    public void rightRotate(){
        Node newNode = new Node(this.value);
        newNode.right = this.right;
        newNode.left = this.left.right;
        this.value = this.left.value;
        this.left = this.left.left;
        this.right = newNode;
    }


}
